package NIO;

import org.junit.Test;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Date;
import java.util.Iterator;

public class TestNotBlockingNIO {

    @Test
    public void client() throws IOException {
        // 获取通道
        SocketChannel sChannel = SocketChannel.open(
                new InetSocketAddress("127.0.0.1", 19897));

        // 切换成非阻塞模式
        sChannel.configureBlocking(false);

        // 分配给定大小缓冲区
        ByteBuffer buf = ByteBuffer.allocate(1024);

        // 发送数据给服务端
        //Scanner scanner = new Scanner(System.in);

        //while (scanner.hasNext()) {
            //String str = scanner.next();
            buf.put((new Date().toString() + "\n").getBytes());
            buf.flip();
            sChannel.write(buf);
            buf.clear();
        //}

        sChannel.close();
    }

    @Test
    public void server() throws IOException {
        ServerSocketChannel ssChannel = ServerSocketChannel.open();

        ssChannel.configureBlocking(false);

        ssChannel.bind(new InetSocketAddress(19897));

        Selector selector = Selector.open();

        // 将通道注册到选择器上
        ssChannel.register(selector, SelectionKey.OP_ACCEPT);

        // 轮询获取选择器上准备就绪的事件
        while (selector.select() > 0){

            Iterator<SelectionKey> it = selector.selectedKeys().iterator();

            while (it.hasNext()){
                SelectionKey sk = it.next();

                if (sk.isAcceptable()){
                    // 获取客户端连接
                    SocketChannel sChannel = ssChannel.accept();

                    // 将客户端通道切换到非阻塞模式
                    sChannel.configureBlocking(false);

                    // 将通道注册到选择器上
                    sChannel.register(selector, SelectionKey.OP_READ);
                } else if (sk.isReadable()){
                    SocketChannel sChannel = (SocketChannel) sk.channel();

                    // 读取数据
                    ByteBuffer buf = ByteBuffer.allocate(1024);
                    int len = 0;
                    while ((len = sChannel.read(buf)) != -1){
                        buf.flip();
                        System.out.println(new String(buf.array(), 0, len));
                        buf.clear();
                    }
                }
                // 取消选择键SelectionKey
                it.remove();
            }
        }
    }
}
